package com.mtiiot.fstcpserver.report;

import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.ReportingEngine;
import com.mtiiot.fstcpserver.fastdfs.FastdfsBase;
import com.mtiiot.fstcpserver.fastdfs.core.NameValuePair;
import com.mtiiot.fstcpserver.utils.PrintBarcodeUtil;
import com.mtiiot.fscore.bean.MetadataInfo;
import com.mtiiot.fscore.bean.ReportInfo;
import com.mtiiot.fscore.bean.TemplateInfo;
import com.mtiiot.fscore.bean.elasticsearch.metadata.ReportMetadata;
import com.mtiiot.fscore.bean.reportdata.ins.insdailyreportdata.InsDailyReportData;
import com.mtiiot.fscore.bean.reportdata.tj.ReportData;
import com.mtiiot.fscore.inter1.ReportService1;
import com.mtiiot.fstcpserver.base.BaseService;
import com.mtiiot.fstcpserver.utils.Constants;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;

/**
 * Created by Administrator on 16-8-19.
 */
public class ReportServiceImpl1 extends BaseService implements ReportService1{
    private static final Logger logger = LogManager.getLogger(ReportServiceImpl1.class);
    private static InputStream license;
    @Autowired
    private FastdfsBase fastdfsBase;
    static{
        try {
            license = ReportServiceImpl1.class.getResourceAsStream("/license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(license);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }
    /**
     * 上传模板
     *
     * @param metadataInfo    元数据信息
     * @param templateAlias
     * @param templateExtType
     * @param templateComment
     * @param file
     * @return
     */
    @Override
    public String uploadTemplate(MetadataInfo metadataInfo, String templateAlias, TemplateExtType templateExtType, String templateComment, byte[] file) {
        String dfsKey=null;
        try{
            checkMetadata(metadataInfo);//验证元数据
            double fileSize=file.length/1024;
            if(fileSize<1){
                fileSize=1;
            }
            ReportMetadata md=new ReportMetadata();
            setMetadataBeanData(metadataInfo,md,RequestType.INSERT.getName());
            md.setFileType(Constants.FASTDFS_FILE_TYPE_REPORT);
            md.setReportTemplate(true);
            md.setExt(templateExtType.getName());
            md.setTemplateComment(templateComment);
            md.setTemplateAlias(templateAlias);
            md.setFileSize(fileSize);
            NameValuePair[] nvp =new NameValuePair[3];
            nvp[0]=new NameValuePair("templateExt",templateExtType.getName());
            nvp[1]=new NameValuePair("templateAlias",templateAlias);
            nvp[2]=new NameValuePair("templateComment",templateComment);
            dfsKey = fastdfsBase.uploadFile(file, templateExtType.getName(),nvp);
            md.setDfsId(dfsKey);
            metadataInQueue(Constants.TOPIC_METADATAINFO, Constants.TYPE_METADATA_FASTDFS, md);

            return dfsKey;
        }catch(Exception ex){
            //异常信息 元数据入reids队列
            handleException(Constants.MODULE_REPORT,"ReportServiceImpl1","uploadTemplate",ex,logger);
            return dfsKey;
        }
    }

    /**
     * 根据模板id下载模板
     *
     * @param metadataInfo 元数据信息
     * @param id           模板id
     * @return
     */
    @Override
    public TemplateInfo downLoadTemplateById(MetadataInfo metadataInfo, String id) {
        try{
            checkMetadata(metadataInfo);//验证元数据
            if(id==null){
                throw new Exception("模板id不能为空!");
            }
            byte[] file=fastdfsBase.downLoadFile(id);
            if(file==null){
                return null;
            }
            NameValuePair[] nvps=fastdfsBase.getMetadata(id);
            TemplateInfo ti=new TemplateInfo();
            if(nvps!=null){
                for(NameValuePair nvp:nvps){
                    String n=nvp.getName();
                    String v=nvp.getValue();
                    if("templateExt".equals(n)){
                        ti.setTemplateExt(v);
                    }
                    if("templateAlias".equals(n)){
                        ti.setTemplateAlias(v);
                    }
                    if("templateComment".equals(n)){
                        ti.setTemplateComment(v);
                    }
                }
            }
            ti.setFile(file);
            ti.setId(id);
            return ti;
        }catch(Exception ex){
            //异常信息 元数据入reids队列
            handleException(Constants.MODULE_REPORT,"ReportServiceImpl1","downLoadTemplateById",ex,logger);
            return null;
        }
    }

    /**
     * 根据id删除模板,
     *
     * @param metadataInfo 元数据信息
     * @param id
     * @return if true success;if false failure
     */
    @Override
    public boolean delTemplateById(MetadataInfo metadataInfo, String id) {
        try{
            checkMetadata(metadataInfo);//验证元数据
            return fastdfsBase.deleteFile(id);
        }catch(Exception ex){
            //异常信息 元数据入reids队列
            handleException(Constants.MODULE_REPORT,"ReportServiceImpl1","delTemplateById",ex,logger);
            return false;
        }
    }

    /**
     * 创建报告单 并返回报告单id
     *
     * @param metadataInfo     元数据信息
     * @param templateId       模板id
     * @param dataSourceBean   数据源bean  根据不同的模板id对应不同的bean
     * @param reportFormatType 报告单输出格式类型
     * @return
     */
    @Override
    public String createReportAndReturnId(MetadataInfo metadataInfo, String templateId, Object dataSourceBean, ReportFormatType reportFormatType) {
        ByteArrayOutputStream baos=null;//barcode图片流
        InputStream is=null;//模板输入文件流
        ByteArrayOutputStream os=null;//报告单输出文件流
        Document doc=null;//文档流.
        String dfsKey=null;
        try{
            checkMetadata(metadataInfo);//验证元数据
            if(StringUtil.isEmpty(templateId)){
                throw new Exception("待生成报告单的指定模板为空!");
            }
            if(dataSourceBean==null){
                throw new Exception("模板id为:"+templateId+"的待生成报告单的数据源为空!");
            }

            if(reportFormatType==null){
                reportFormatType=ReportFormatType.PDF;//默认是pdf
            }
            //获取模板信息
            TemplateInfo tif=downLoadTemplateById(new MetadataInfo(Constants.SYS_ID_FS),templateId);
            if(tif==null){
                throw new Exception("模板id为:"+templateId+"的模板在系统中不存在!");
            }

            if(dataSourceBean.getClass().isAssignableFrom(ReportData.class)){
                //体检报告单
                ReportData rd= (ReportData) dataSourceBean;
                String barcode=rd.barcode;
                if(StringUtil.isEmpty(barcode)){
                    throw new Exception("模板id为:" + templateId + "的待生成报告单的barcode为空!");
                }
                //生成条形码
                baos = PrintBarcodeUtil.getPrintBarcodeUtil(barcode);
                rd.image=baos.toByteArray();

                is=new ByteArrayInputStream(tif.getFile()) ;//获取模板输入文件流
                os=new ByteArrayOutputStream();
                doc = new Document(is);
                ReportingEngine engine = new ReportingEngine();
                engine.buildReport(doc, dataSourceBean, "rd");
                doc.save(os,reportFormatType.getFormatType());//生成报告单
            }else if(dataSourceBean.getClass().isAssignableFrom(InsDailyReportData.class)){
                //仪器日结报告单
                InsDailyReportData rd=(InsDailyReportData)dataSourceBean;
                is=new ByteArrayInputStream(tif.getFile()) ;//获取模板输入文件流
                os=new ByteArrayOutputStream();
                doc = new Document(is);
                ReportingEngine engine = new ReportingEngine();
                engine.buildReport(doc, dataSourceBean, "rd");
                doc.save(os,reportFormatType.getFormatType());//生成报告单
            }else{
                throw new Exception("模板id为:" + templateId + "的待生成报告单的数据源bean不是系统指定bean!");
            }
            byte[] reportFile=os.toByteArray();//生成报告单文件字节流

            double fileSize=reportFile.length/1024;
            if(fileSize<1){
                fileSize=1;
            }
            int page=doc.getPageCount();

            //报告单元数据入队列
            ReportMetadata md=new ReportMetadata();
            setMetadataBeanData(metadataInfo,md,RequestType.INSERT.getName());
            md.setFileType(Constants.FASTDFS_FILE_TYPE_REPORT);
            md.setReportTemplate(false);
            md.setExt(reportFormatType.getExt());
            md.setReportPage(page);
            md.setFileSize(fileSize);
            NameValuePair[] nvp =new NameValuePair[3];
            nvp[0]=new NameValuePair("reportExt",reportFormatType.getExt());
            nvp[1]=new NameValuePair("reportPage",Integer.toString(page));
            nvp[2]=new NameValuePair("templateId",templateId);
            dfsKey = fastdfsBase.uploadFile(reportFile,reportFormatType.getExt(),nvp);
            md.setDfsId(dfsKey);
            metadataInQueue(Constants.TOPIC_METADATAINFO, Constants.TYPE_METADATA_FASTDFS, md);

            return dfsKey;
        }catch(Exception ex){
            //异常信息 元数据入reids队列
            handleException(Constants.MODULE_REPORT,"ReportServiceImpl1","createReportAndReturnId",ex,logger);
            return dfsKey;
        }finally {
            try {
                if(baos!=null){
                    baos.close();
                }
                if(is!=null){
                    is.close();
                }
                if(os!=null){
                    os.close();
                }
            }catch (IOException e) {
                //异常信息 元数据入reids队列
                handleException(Constants.MODULE_REPORT, "ReportServiceImpl1", "createReportAndReturnId", e, logger);
            }
        }
    }

    /**
     * 创建报告单
     *
     * @param metadataInfo     元数据信息
     * @param templateId       模板id
     * @param dataSourceBean   数据源bean  根据不同的模板id对应不同的bean
     * @param reportFormatType 报告单输出格式类型
     * @return
     */
    @Override
    public ReportInfo createReport(MetadataInfo metadataInfo, String templateId, Object dataSourceBean, ReportFormatType reportFormatType) {
        ByteArrayOutputStream baos=null;//barcode图片流
        InputStream is=null;//模板输入文件流
        ByteArrayOutputStream os=null;//报告单输出文件流
        Document doc=null;//文档流.
        ReportInfo  reportInfo=null;
        try{
            checkMetadata(metadataInfo);//验证元数据
            if(StringUtil.isEmpty(templateId)){
                throw new Exception("待生成报告单的指定模板为空!");
            }
            if(dataSourceBean==null){
                throw new Exception("模板id为:"+templateId+"的待生成报告单的数据源为空!");
            }

            if(reportFormatType==null){
                reportFormatType=ReportFormatType.PDF;//默认是pdf
            }
            //获取模板信息
            TemplateInfo tif=downLoadTemplateById(new MetadataInfo(Constants.SYS_ID_FS),templateId);
            if(tif==null){
                throw new Exception("模板id为:"+templateId+"的模板在系统中不存在!");
            }

            if(dataSourceBean.getClass().isAssignableFrom(ReportData.class)){
                //体检报告单
                ReportData rd= (ReportData) dataSourceBean;
                String barcode=rd.barcode;
                if(StringUtil.isEmpty(barcode)){
                    throw new Exception("模板id为:" + templateId + "的待生成报告单的barcode为空!");
                }
                //生成条形码
                baos = PrintBarcodeUtil.getPrintBarcodeUtil(barcode);
                rd.image=baos.toByteArray();

                is=new ByteArrayInputStream(tif.getFile()) ;//获取模板输入文件流
                os=new ByteArrayOutputStream();
                doc = new Document(is);
                ReportingEngine engine = new ReportingEngine();
                engine.buildReport(doc, dataSourceBean, "rd");
                doc.save(os,reportFormatType.getFormatType());//生成报告单
            }else if(dataSourceBean.getClass().isAssignableFrom(InsDailyReportData.class)){
                //仪器日结报告单
                InsDailyReportData rd=(InsDailyReportData)dataSourceBean;
                is=new ByteArrayInputStream(tif.getFile()) ;//获取模板输入文件流
                os=new ByteArrayOutputStream();
                doc = new Document(is);
                ReportingEngine engine = new ReportingEngine();
                engine.buildReport(doc, dataSourceBean, "rd");
                doc.save(os,reportFormatType.getFormatType());//生成报告单
            }else{
                throw new Exception("模板id为:" + templateId + "的待生成报告单的数据源bean不是系统指定bean!");
            }
            byte[] reportFile=os.toByteArray();//生成报告单文件字节流

            double fileSize=reportFile.length/1024;
            if(fileSize<1){
                fileSize=1;
            }
            int page=doc.getPageCount();
            NameValuePair[] nvp =new NameValuePair[3];
            nvp[0]=new NameValuePair("reportExt",reportFormatType.getExt());
            nvp[1]=new NameValuePair("reportPage",Integer.toString(page));
            nvp[2]=new NameValuePair("templateId",templateId);
            String dfsKey = fastdfsBase.uploadFile(reportFile,reportFormatType.getExt(),nvp);
            //返回报告单信息
            reportInfo=new ReportInfo();
            reportInfo.setId(dfsKey);
            reportInfo.setTemplateId(templateId);
            reportInfo.setFile(reportFile);
            reportInfo.setReportExt(reportFormatType.getExt());
            reportInfo.setPage(page);

            //报告单元数据入队列
            ReportMetadata md=new ReportMetadata();
            setMetadataBeanData(metadataInfo,md,RequestType.INSERT.getName());
            md.setFileType(Constants.FASTDFS_FILE_TYPE_REPORT);
            md.setReportTemplate(false);
            md.setExt(reportFormatType.getExt());
            md.setReportPage(page);
            md.setFileSize(fileSize);
            md.setDfsId(dfsKey);
            metadataInQueue(Constants.TOPIC_METADATAINFO, Constants.TYPE_METADATA_FASTDFS, md);

            return reportInfo;
        }catch(Exception ex){
            //异常信息 元数据入reids队列
            handleException(Constants.MODULE_REPORT,"ReportServiceImpl1","createReport",ex,logger);
            return reportInfo;
        }finally {
            try {
                if(baos!=null){
                    baos.close();
                }
                if(is!=null){
                    is.close();
                }
                if(os!=null){
                    os.close();
                }
            }catch (IOException e) {
                //异常信息 元数据入reids队列
                handleException(Constants.MODULE_REPORT, "ReportServiceImpl1", "createReport", e, logger);
            }
        }
    }

    /**
     * 根据报告单id下载报告单
     *
     * @param metadataInfo 元数据信息
     * @param id           报告单id
     * @return
     */
    @Override
    public ReportInfo downLoadReportById(MetadataInfo metadataInfo, String id) {
        try{
            checkMetadata(metadataInfo);//验证元数据
            //返回报告单信息
            ReportInfo  reportInfo=new ReportInfo();
            byte[] file=fastdfsBase.downLoadFile(id);
            if(file==null){
                return null;
            }
            NameValuePair[] nvps=fastdfsBase.getMetadata(id);
            TemplateInfo ti=new TemplateInfo();
            if(nvps!=null){
                for(NameValuePair nvp:nvps){
                    String n=nvp.getName();
                    String v=nvp.getValue();
                    if("templateId".equals(n)){
                        reportInfo.setTemplateId(v);
                    }
                    if("reportPage".equals(n)){
                        reportInfo.setPage(Integer.parseInt(v));
                    }
                    if("reportExt".equals(n)){
                        reportInfo.setReportExt(v);
                    }
                }
            }
            reportInfo.setId(id);
            reportInfo.setFile(file);
            return reportInfo;
        }catch(Exception ex){
            //异常信息 元数据入reids队列
            handleException(Constants.MODULE_REPORT,"ReportServiceImpl1","downLoadReportById",ex,logger);
            return null;
        }
    }

    /**
     *
     * @param args
     */
    public static void main(String[] args){
        InputStream is= null;
        try {
            is = new FileInputStream(new File("D:/template/仪器日结报告单.docx"));
            Document doc = new Document(is);
            ReportingEngine engine = new ReportingEngine();
            InsDailyReportData idd=new InsDailyReportData();
            idd.insName="仪器名称";
            idd.date="2016-10-11";
            Object obj=idd;
            engine.buildReport(doc, obj, "rd");
            OutputStream os=new FileOutputStream(new File("D:/template/仪器日结报告单2.pdf"));
            doc.save(os,40);//生成报告单
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
